En omfattende guide til Content Security Policy (CSP) og andre frontend security headers, der beskytter webapplikationer mod angreb og forbedrer brugersikkerheden globalt.
Frontend Security Headers: Mestring af Content Security Policy (CSP)
I nutidens digitale landskab, hvor webapplikationer bliver stadig mere komplekse og forbundne, er beskyttelse mod sikkerhedstrusler altafgørende. Mens backend-sikkerhed ofte får betydelig opmærksomhed, er frontend-sikkerhed lige så kritisk. Frontend security headers fungerer som den første forsvarslinje og giver en mekanisme til at instruere browseren i, hvordan den skal opføre sig og beskytte brugere mod forskellige angreb. Blandt disse headers skiller Content Security Policy (CSP) sig ud som et stærkt værktøj til at afbøde en bred vifte af risici.
Hvad er Frontend Security Headers?
Frontend security headers er HTTP-svarheadere, som en webserver sender til browseren. Disse headers indeholder instruktioner om, hvordan browseren skal håndtere det indhold, den modtager. De hjælper med at forhindre almindelige angreb som:
- Cross-Site Scripting (XSS): Indsprøjtning af ondsindede scripts i betroede websteder.
- Clickjacking: At narre brugere til at klikke på noget andet, end hvad de opfatter.
- Man-in-the-Middle Angreb: Aflytning af kommunikation mellem brugeren og serveren.
Nogle af de vigtigste frontend security headers inkluderer:
- Content Security Policy (CSP): Definerer de kilder, hvorfra browseren må indlæse ressourcer.
- Strict-Transport-Security (HSTS): Tvinger browseren til at bruge HTTPS til al kommunikation med webstedet.
- X-Frame-Options: Forhindrer webstedet i at blive indlejret i en iframe, hvilket afbøder clickjacking-angreb.
- X-XSS-Protection: Aktiverer browserens indbyggede XSS-filter. (Bemærk: Ofte erstattet af CSP, men kan stadig give et lag af forsvar).
- Referrer-Policy: Styrer mængden af referrer-information, der sendes med anmodninger.
- Feature-Policy (nu Permissions-Policy): Giver udviklere mulighed for selektivt at aktivere og deaktivere browserfunktioner og API'er.
Dybdegående Gennemgang af Content Security Policy (CSP)
Content Security Policy (CSP) er en HTTP-svarheader, der styrer, hvilke ressourcer brugeragenten må indlæse for en given side. Den whitelister i bund og grund kilder til godkendt indhold, hvilket markant reducerer risikoen for XSS-angreb. Ved eksplicit at definere de oprindelser, hvorfra ressourcer som scripts, stylesheets, billeder og skrifttyper kan indlæses, gør CSP det meget sværere for angribere at injicere ondsindet kode på dit websted.
Hvordan CSP Virker
CSP virker ved at give browseren en liste over godkendte kilder for forskellige typer indhold. Når browseren støder på en ressource, der overtræder CSP'en, blokerer den ressourcen og rapporterer overtrædelsen. Denne blokeringsmekanisme forhindrer ondsindet kode i at blive udført, selvom en angriber formår at injicere den i HTML'en.
CSP-direktiver
CSP-direktiver er kernekomponenterne i en CSP-politik. De specificerer de tilladte kilder for forskellige typer ressourcer. Nogle af de mest almindeligt anvendte direktiver inkluderer:
- default-src: Sætter standardkilden for alle ressourcetyper. Dette er et fallback-direktiv, der gælder, når andre mere specifikke direktiver ikke er defineret.
- script-src: Specificerer de tilladte kilder for JavaScript.
- style-src: Specificerer de tilladte kilder for CSS-stylesheets.
- img-src: Specificerer de tilladte kilder for billeder.
- font-src: Specificerer de tilladte kilder for skrifttyper.
- media-src: Specificerer de tilladte kilder for lyd og video.
- object-src: Specificerer de tilladte kilder for plugins som Flash. (Generelt bedst at undgå at tillade plugins, hvis det er muligt).
- frame-src: Specificerer de tilladte kilder for frames (iframes).
- connect-src: Specificerer de tilladte kilder for netværksanmodninger (AJAX, WebSockets).
- base-uri: Begrænser de URL'er, der kan bruges i et
<base>-element. - form-action: Begrænser de URL'er, som formularer kan sendes til.
- frame-ancestors: Specificerer gyldige forældre, der må indlejre en side ved hjælp af
<frame>,<iframe>,<object>,<embed>, eller<applet>. Dette direktiv giver beskyttelse mod Clickjacking. - upgrade-insecure-requests: Instruerer brugeragenter om at behandle alle et websteds usikre URL'er (indlæst over HTTP), som om de var blevet erstattet med sikre URL'er (indlæst over HTTPS). Dette direktiv er beregnet til websteder, der er i gang med at migrere fra HTTP til HTTPS.
- report-uri: Specificerer en URL, som browseren skal sende rapporter om CSP-overtrædelser til. Forældet til fordel for `report-to`.
- report-to: Specificerer et gruppenavn defineret i en `Report-To`-header. Dette giver mere finkornet kontrol over rapportering, herunder specificering af flere rapporteringsendepunkter.
CSP Kildeværdier
Kildeværdier definerer de oprindelser, hvorfra ressourcer må indlæses. Nogle almindelige kildeværdier inkluderer:
- *: Tillader indhold fra enhver kilde (Undgå at bruge dette i produktion!).
- 'self': Tillader indhold fra samme oprindelse (skema, vært og port) som det beskyttede dokument.
- 'none': Tillader ikke indhold fra nogen kilde.
- 'unsafe-inline': Tillader brugen af inline JavaScript og CSS (Undgå at bruge dette i produktion!).
- 'unsafe-eval': Tillader brugen af dynamisk kodeevaluering (f.eks.
eval(),Function()) (Undgå at bruge dette i produktion!). - 'strict-dynamic': Specificerer, at den tillid, der eksplicit er givet til et script til stede i markup'en, ved at ledsage det med en nonce eller hash, skal udbredes til alle scripts, der indlæses af den forfader.
- 'unsafe-hashes': Tillader specifikke inline hændelseshåndterere. Dette frarådes generelt på grund af dets kompleksitet og begrænsede fordel.
- data:: Tillader indlæsning af ressourcer fra data-URL'er (f.eks. indlejrede billeder). Brug med forsigtighed.
- mediastream:: Tillader, at `mediastream:` URI'er bruges som mediekilde.
- blob:: Tillader, at `blob:` URI'er bruges som mediekilde.
- filesystem:: Tillader, at ressourcer indlæses fra et filsystem.
- https://example.com: Tillader indhold fra et specifikt domæne og port.
- *.example.com: Tillader indhold fra ethvert underdomæne af example.com.
- nonce-{random-value}: Tillader scripts eller styles med et matchende nonce-attribut. Dette kræver serversidegenerering af en tilfældig nonce-værdi for hver anmodning.
- sha256-{hash-value}: Tillader scripts eller styles med en matchende SHA256-, SHA384- eller SHA512-hash.
CSP-tilstande: Håndhæv vs. Kun-Rapportering
CSP kan implementeres i to tilstande:
- Håndhævelsestilstand: I denne tilstand blokerer browseren alle ressourcer, der overtræder CSP'en. Dette er den anbefalede tilstand for produktionsmiljøer. CSP'en sendes ved hjælp af `Content-Security-Policy`-headeren.
- Kun-rapporteringstilstand: I denne tilstand rapporterer browseren CSP-overtrædelser, men blokerer ikke ressourcerne. Dette er nyttigt til at teste og evaluere en CSP, før den håndhæves. CSP'en sendes ved hjælp af `Content-Security-Policy-Report-Only`-headeren.
Implementering af CSP: En Trin-for-Trin Guide
Implementering af CSP kan virke skræmmende, men ved at følge en struktureret tilgang kan du effektivt sikre din webapplikation.
1. Start med en Kun-Rapporteringspolitik
Begynd med at implementere en CSP i kun-rapporteringstilstand. Dette giver dig mulighed for at overvåge overtrædelser uden at forstyrre dit websteds funktionalitet. Konfigurer report-uri- eller report-to-direktivet til at sende overtrædelsesrapporter til et udpeget endepunkt.
Eksempelheader (Kun-Rapportering):
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
2. Analyser Overtrædelsesrapporterne
Analyser omhyggeligt overtrædelsesrapporterne for at identificere, hvilke ressourcer der bliver blokeret og hvorfor. Dette vil hjælpe dig med at forstå dit websteds ressourceafhængigheder og identificere potentielle sikkerhedssårbarheder.
Overtrædelsesrapporter sendes typisk som JSON-payloads til det konfigurerede report-uri- eller report-to-endepunkt. Disse rapporter indeholder information om overtrædelsen, såsom den blokerede URI, det overtrådte direktiv og dokumentets URI.
3. Finpuds CSP-politikken
Baseret på overtrædelsesrapporterne, finpuds din CSP-politik for at tillade legitime ressourcer, mens du stadig opretholder en stærk sikkerhedsposition. Tilføj specifikke kildeværdier for de ressourcer, der bliver blokeret. Overvej at bruge nonces eller hashes til inline scripts og styles for at undgå at bruge 'unsafe-inline'.
4. Overgang til Håndhævelsestilstand
Når du er sikker på, at din CSP-politik ikke blokerer legitime ressourcer, skal du skifte til håndhævelsestilstand. Dette vil blokere eventuelle resterende overtrædelser og give et robust lag af sikkerhed mod XSS-angreb.
Eksempelheader (Håndhævelse):
Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report
5. Overvåg og Vedligehold CSP-politikken
CSP er ikke en 'sæt-og-glem'-løsning. Det er vigtigt løbende at overvåge din CSP-politik og opdatere den, efterhånden som dit websted udvikler sig, og nye sikkerhedstrusler opstår. Gennemgå jævnligt overtrædelsesrapporter og juster politikken efter behov.
Praktiske CSP-eksempler
Lad os se på nogle praktiske CSP-eksempler for forskellige scenarier:
Eksempel 1: Grundlæggende CSP for et Simpelt Websted
Denne CSP tillader indhold fra samme oprindelse og tillader billeder fra enhver kilde.
Content-Security-Policy: default-src 'self'; img-src *
Eksempel 2: CSP med Specifikke Script- og Style-kilder
Denne CSP tillader scripts fra samme oprindelse og fra en specifik CDN, samt styles fra samme oprindelse og inline styles.
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'
Eksempel 3: CSP med Nonces for Inline Scripts
Denne CSP kræver en unik nonce for hvert inline script.
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-r4nd0mn0nc3'
HTML:
<script nonce="r4nd0mn0nc3">console.log('Hello, world!');</script>
Vigtigt: Nonce-værdien skal genereres dynamisk på serveren for hver anmodning. Dette forhindrer angribere i at genbruge noncen.
Eksempel 4: CSP der Begrænser Frame Ancestors for at Forhindre Clickjacking
Denne CSP forhindrer siden i at blive indlejret i en iframe på ethvert domæne undtagen `https://example.com`.
Content-Security-Policy: frame-ancestors 'self' https://example.com
Eksempel 5: En mere restriktiv CSP med 'strict-dynamic' og en fallback til 'self'
Denne CSP udnytter `strict-dynamic` for moderne browsere, mens den stadig understøtter ældre browsere, der ikke understøtter det. Den inkluderer også en `report-uri` til overvågning af overtrædelser.
Content-Security-Policy: default-src 'self'; script-src 'strict-dynamic' 'nonce-{random-nonce}' 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report
Husk at erstatte `{random-nonce}` med en dynamisk genereret nonce-værdi på serversiden.
CSP og Single-Page Applications (SPA'er)
Implementering af CSP i SPA'er kan være udfordrende på grund af disse applikationers dynamiske natur. SPA'er er ofte stærkt afhængige af JavaScript til at generere og manipulere DOM'en, hvilket kan føre til CSP-overtrædelser, hvis det ikke håndteres omhyggeligt.
Her er nogle tips til implementering af CSP i SPA'er:
- Undgå
'unsafe-inline'og'unsafe-eval': Disse direktiver bør undgås, når det er muligt i SPA'er. De svækker sikkerheden i din applikation betydeligt. - Brug Nonces eller Hashes: Brug nonces eller hashes til inline scripts og styles. Dette er den anbefalede tilgang for SPA'er.
- Overvej Trusted Types: Trusted Types er en browser-API, der hjælper med at forhindre DOM-baserede XSS-sårbarheder. Det kan bruges sammen med CSP for yderligere at forbedre sikkerheden.
- Brug et CSP-kompatibelt framework: Nogle frontend-frameworks (som React med specifikke konfigurationer, Angular og Vue.js) tilbyder funktioner, der kan hjælpe dig med at implementere CSP lettere.
Andre Vigtige Frontend Security Headers
Selvom CSP er en hjørnesten i frontend-sikkerhed, spiller andre headers en afgørende rolle i at levere en omfattende forsvarsstrategi:
Strict-Transport-Security (HSTS)
Strict-Transport-Security (HSTS)-headeren instruerer browseren om altid at bruge HTTPS til at forbinde til webstedet. Dette forhindrer man-in-the-middle-angreb, der forsøger at nedgradere forbindelsen til HTTP.
Eksempelheader:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age: Specificerer varigheden (i sekunder), som browseren skal huske kun at tilgå webstedet via HTTPS. En værdi på 31536000 sekunder (1 år) anbefales for produktionsmiljøer.includeSubDomains: Angiver, at HSTS-politikken gælder for alle underdomæner af domænet.preload: Tillader, at domænet inkluderes i en liste over HSTS-aktiverede domæner, der er forudindlæst i browsere. Dette kræver, at du indsender dit domæne til HSTS-preload-listen, der vedligeholdes af Google.
X-Frame-Options
X-Frame-Options-headeren forhindrer clickjacking-angreb ved at kontrollere, om webstedet kan indlejres i en iframe.
Eksempelheader:
X-Frame-Options: DENY
Mulige værdier:
DENY: Forhindrer siden i at blive vist i en iframe, uanset oprindelsen.SAMEORIGIN: Tillader, at siden vises i en iframe, kun hvis iframens oprindelse matcher sidens oprindelse.ALLOW-FROM uri: Tillader, at siden vises i en iframe, kun hvis iframens oprindelse matcher den specificerede URI. Bemærk: Denne mulighed er forældet og understøttes muligvis ikke af alle browsere.
Bemærk: frame-ancestors-direktivet i CSP giver en mere fleksibel og kraftfuld måde at kontrollere framing på og foretrækkes generelt frem for X-Frame-Options.
X-XSS-Protection
X-XSS-Protection-headeren aktiverer browserens indbyggede XSS-filter. Selvom CSP er en mere robust løsning til at forhindre XSS-angreb, kan denne header give et ekstra lag af forsvar, især for ældre browsere, der muligvis ikke fuldt ud understøtter CSP.
Eksempelheader:
X-XSS-Protection: 1; mode=block
1: Aktiverer XSS-filteret.0: Deaktiverer XSS-filteret.mode=block: Instruerer browseren om at blokere siden, hvis et XSS-angreb opdages.report=uri: Specificerer en URL, som browseren skal sende en rapport til, hvis et XSS-angreb opdages.
Referrer-Policy
Referrer-Policy-headeren styrer mængden af referrer-information, der sendes med anmodninger. Referrer-information kan bruges til at spore brugere på tværs af websteder, så kontrol over den kan forbedre brugernes privatliv.
Eksempelheader:
Referrer-Policy: strict-origin-when-cross-origin
Nogle almindelige værdier:
no-referrer: Send aldrig Referer-headeren.no-referrer-when-downgrade: Send ikke Referer-headeren til oprindelser uden TLS (HTTPS).origin: Send kun oprindelsen (skema, vært og port) i Referer-headeren.origin-when-cross-origin: Send oprindelsen for cross-origin anmodninger og den fulde URL for same-origin anmodninger.same-origin: Send Referer-headeren for same-origin anmodninger, men ikke for cross-origin anmodninger.strict-origin: Send kun oprindelsen, når protokolsikkerhedsniveauet forbliver det samme (HTTPS til HTTPS), men send ingen header til en mindre sikker destination (HTTPS til HTTP).strict-origin-when-cross-origin: Send oprindelsen, når der udføres en same-origin anmodning. For cross-origin anmodninger, send kun oprindelsen, når protokolsikkerhedsniveauet forbliver det samme (HTTPS til HTTPS), men send ingen header til en mindre sikker destination (HTTPS til HTTP).unsafe-url: Send den fulde URL i Referer-headeren, uanset oprindelse. Brug med ekstrem forsigtighed, da dette kan afsløre følsomme oplysninger.
Permissions-Policy (tidligere Feature-Policy)
Permissions-Policy-headeren (tidligere kendt som Feature-Policy) giver udviklere mulighed for selektivt at aktivere og deaktivere browserfunktioner og API'er. Dette kan hjælpe med at reducere angrebsfladen for din applikation og forbedre brugernes privatliv.
Eksempelheader:
Permissions-Policy: geolocation=()
Dette eksempel deaktiverer geolocation-API'en for webstedet.
Andre funktioner, der kan styres med Permissions-Policy, inkluderer:
cameramicrophonegeolocationaccelerometergyroscopemagnetometerusbmidipaymentfullscreen
Indstilling af Security Headers på Forskellige Platforme
Metoden til at indstille security headers varierer afhængigt af den webserver eller platform, du bruger. Her er nogle almindelige eksempler:
Apache
Du kan indstille security headers i Apache ved at tilføje dem til .htaccess-filen eller serverkonfigurationsfilen (httpd.conf).
Eksempel på .htaccess-konfiguration:
<IfModule mod_headers.c>
Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report"
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header set X-Frame-Options "DENY"
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
Nginx
Du kan indstille security headers i Nginx ved at tilføje dem til serverblokken i Nginx-konfigurationsfilen (nginx.conf).
Eksempel på Nginx-konfiguration:
server {
listen 443 ssl;
server_name example.com;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Frame-Options "DENY";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
...
}
Node.js (Express)
Du kan indstille security headers i Node.js ved hjælp af middleware som Helmet.
Eksempel med Helmet:
const express = require('express');
const helmet = require('helmet');
const app = express();
app.use(helmet());
// Tilpas CSP efter behov
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "https://cdn.example.com"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:"],
reportUri: '/csp-report'
},
}));
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
Cloudflare
Cloudflare giver dig mulighed for at indstille security headers ved hjælp af deres Page Rules eller Transform Rules.
Test af Dine Security Headers
Efter implementering af security headers er det afgørende at teste dem for at sikre, at de fungerer korrekt. Flere online værktøjer kan hjælpe dig med at analysere dit websteds security headers:
- SecurityHeaders.com: Et simpelt og effektivt værktøj til at analysere security headers.
- Mozilla Observatory: Et omfattende værktøj til at teste webstedssikkerhed, herunder security headers.
- WebPageTest.org: Giver dig mulighed for at se HTTP-headers i vandfaldsdiagrammet.
Konklusion
Frontend security headers, især Content Security Policy (CSP), er essentielle for at beskytte webapplikationer mod forskellige angreb og forbedre brugersikkerheden. Ved omhyggeligt at implementere og vedligeholde disse headers kan du markant reducere risikoen for XSS, clickjacking og andre sikkerhedssårbarheder. Husk at starte med en kun-rapporteringspolitik, analysere overtrædelsesrapporterne, finpudse politikken og derefter skifte til håndhævelsestilstand. Overvåg og opdater jævnligt dine security headers for at holde dit websted sikkert, efterhånden som det udvikler sig, og nye trusler opstår.
Ved at anlægge en proaktiv tilgang til frontend-sikkerhed kan du bygge mere sikre og troværdige webapplikationer, der beskytter dine brugere og din virksomhed.